<?php

namespace App\LogicService;

use App\LogicService\Contracts\SamGlucoseLogicContract;
use App\Models\Dynamic\SamGlucose;
use Illuminate\Support\Facades\DB;

class SamGlucoseLogic extends BaseLogic implements SamGlucoseLogicContract
{
    public function getAllWearData($userid, $startTime, $endTime)
    {
        if ($userid) {
            $array = SamGlucose::getListByUIdByTime($userid, $startTime, $endTime)
                ->select(DB::raw("AVG(value) as avg,MAX(value) as max,MIN(value) as min,COUNT(id) as count"))
                ->get()
                ->toArray();
            //平均值
            $avg = $array['0']['avg'];
            //最大值
            $max = $array['0']['max'];
            //最小值
            $min = $array['0']['min'];
            //总条数
            $count = $array['0']['count'];

            //查询佩戴及路对应的血糖数据
            $glucose = SamGlucose::getListByUIdByTime($userid, $startTime, $endTime)
                ->orderBy('id','desc')
                ->get()
                ->toArray();

            $sum = 0;
            //计算水平标准差
            if ($glucose) {
                foreach ($glucose as $gk => $gv) {
                    $sum += pow($gv['value'] - $avg, 2);
                }
                $sum = number_format(@sqrt($sum / ($gk)), 1);
            }

            //计算最大波动幅度
            $spacing = number_format($max - $min, 1);

            unset($glucose, $where);
            $array = array(
                'avg' => $avg,
                'max' => $max,
                'min' => $min,
                'count' => $count,
                'sdbg' => $sum,
                'spacing' => $spacing,
            );
            return $array;
        }
        return false;
    }

    /**
     * @param $user_id
     * @param $start_time
     * @param $end_time
     * @return string
     */
    public function getEffective($user_id, $start_time, $end_time)
    {
        //有效点
        $count = SamGlucose::whereUserid($user_id)
            ->whereBetween('collectedtime', [$start_time, $end_time])
            ->count('id');

        //查询当天第一条录入时间
        $start_glood = SamGlucose::whereUserid($user_id)
            ->whereBetween('collectedtime', [$start_time, $end_time])
            ->orderBy('collectedtime', 'asc')
            ->first();

        //查询当天最后一条数据录入时间
        $end_glood = SamGlucose::whereUserid($user_id)
            ->whereBetween('collectedtime', [$start_time, $end_time])
            ->orderBy('collectedtime', 'desc')
            ->first();

        if ($count == 0) {
            $time_difference = 0;
        } else {
            //有效时间
            $time_difference = ceil((strtotime($end_glood->collectedtime) - strtotime($start_glood->collectedtime)) / (60 * 60));
        }
        $return_data = $time_difference . "小时/" . $count;
        return $return_data;
    }


    /**
     *
     * @param $user_id
     * @param $start_time
     * @param $end_time
     * @return string
     */
    public function getGloodAVG($user_id, $start_time, $end_time)
    {
        $avg = SamGlucose::whereUserid($user_id)
            ->whereBetween('collectedtime', [$start_time, $end_time])
            ->avg('value');

        $return_data = sprintf("%.2f", $avg);
        return $return_data;
    }


    /**
     * @param $user_id
     * @param $start_time
     * @param $end_time
     * @param $startValue
     * @param int $endValue
     * @return float|int|string
     */
    public function getBloodThan($user_id, $start_time, $end_time, $startValue, $endValue = 100)
    {
        //有效点
        $count = SamGlucose::whereUserid($user_id)
            ->whereBetween('collectedtime', [$start_time, $end_time])
            ->count('id');
        $thanCount = SamGlucose::whereUserid($user_id)
            ->whereBetween('collectedtime', [$start_time, $end_time])
            ->whereBetween('value', [$startValue, $endValue])
            ->count('id');

        if ($thanCount == 0) {
            return "0%";
        }
        $division = sprintf("%.2f", ($thanCount / $count)) * 100;
        $division = $division . "%";
        return $division;
    }

    /**
     * @param $user_id
     * @param $start_time
     * @param $end_time
     * @return mixed
     */
    public function getSDBG($user_id, $start_time, $end_time)
    {        //有效点
        $statistical_data = SamGlucose::whereUserid($user_id)
            ->whereBetween('collectedtime', [$start_time, $end_time])
            ->select(\DB::raw("AVG(value) as avg , MAX(value) as max , MIN(value) as min,count(id) as num"))
            ->get()
            ->toArray();
        $glucose = SamGlucose::whereUserid($user_id)
            ->whereBetween('collectedtime', [$start_time, $end_time])
            ->orderBy('collectedtime', 'desc')
            ->get()
            ->toArray();

        $sum = 0;
        //计算水平标准差
        if ($glucose) {
            foreach ($glucose as $gk => $gv) {
                $sum += pow($gv['value'] - $statistical_data[0]['avg'], 2);
            }
            $sum = number_format(@sqrt($sum / ($gk)), 1);
            if ($sum == 0) {
                $return[0] = 0;
            } else {
                $return[0] = $sum;
            }
            $poor = sprintf('%.2f', ($statistical_data[0]['max'] - $statistical_data[0]['min']));
            if ($poor == 0) {
                $return[1] = 0;
            } else {
                $return[1] = $poor;
            }
            return $return;
        }
    }

    /**
     * @param $user_id
     * @param $start_time
     * @param $end_time
     * @return int|string
     */
    public function getMODD($user_id, $start_time, $end_time)
    {
        $glucose = SamGlucose::whereUserid($user_id)
            ->whereBetween('collectedtime', [$start_time, $end_time])
            ->orderBy('collectedtime', 'desc')
            ->get()
            ->toArray();
        $sum1 = 0;
        $sum2 = 0;
        $n = 0;
        foreach ($glucose as $k => $v) {
            $sum1 += pow($v['value'], 2);
            $sum2 += $v['value'];
            $n = $k;
        }
        $sum1 = ($n + 1) * $sum1;
        $sum2 = pow($sum2, 2);
        if ($sum1 - $sum2 == 0) {
            return 0;
        }
        $total = ($sum1 - $sum2) / (($n + 1) * $n);
        $result = sprintf("%.2f", sqrt($total));
        return $result;
    }
}